package migrations

import (
	"database/sql"
	"fmt"
)

// MigrateBlockedIssuesCache creates the blocked_issues_cache table for performance optimization
// This cache materializes the recursive CTE computation from GetReadyWork to avoid
// expensive recursive queries on every call (bd-5qim)
func MigrateBlockedIssuesCache(db *sql.DB) error {
	// Check if table already exists
	var tableName string
	err := db.QueryRow(`
		SELECT name FROM sqlite_master
		WHERE type='table' AND name='blocked_issues_cache'
	`).Scan(&tableName)

	if err == sql.ErrNoRows {
		// Create the cache table
		_, err := db.Exec(`
			CREATE TABLE blocked_issues_cache (
				issue_id TEXT NOT NULL,
				PRIMARY KEY (issue_id),
				FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE
			)
		`)
		if err != nil {
			return fmt.Errorf("failed to create blocked_issues_cache table: %w", err)
		}

		// Populate the cache with initial data using the existing recursive CTE logic
		_, err = db.Exec(`
			INSERT INTO blocked_issues_cache (issue_id)
			WITH RECURSIVE
			  -- Step 1: Find issues blocked directly by dependencies
			  blocked_directly AS (
			    SELECT DISTINCT d.issue_id
			    FROM dependencies d
			    JOIN issues blocker ON d.depends_on_id = blocker.id
			    WHERE d.type = 'blocks'
			      AND blocker.status IN ('open', 'in_progress', 'blocked')
			  ),

			  -- Step 2: Propagate blockage to all descendants via parent-child
			  blocked_transitively AS (
			    -- Base case: directly blocked issues
			    SELECT issue_id, 0 as depth
			    FROM blocked_directly

			    UNION ALL

			    -- Recursive case: children of blocked issues inherit blockage
			    SELECT d.issue_id, bt.depth + 1
			    FROM blocked_transitively bt
			    JOIN dependencies d ON d.depends_on_id = bt.issue_id
			    WHERE d.type = 'parent-child'
			      AND bt.depth < 50
			  )
			SELECT DISTINCT issue_id FROM blocked_transitively
		`)
		if err != nil {
			return fmt.Errorf("failed to populate blocked_issues_cache: %w", err)
		}

		return nil
	}

	if err != nil {
		return fmt.Errorf("failed to check for blocked_issues_cache table: %w", err)
	}

	// Table already exists
	return nil
}
